<template>
  <div class="oy-table">
    <div v-if="showToolbar" class="oy-table__header">
      <div class="oy-table__header-name">
        <i v-if="title" class="font_family icon-hetongmobanguanli"></i><span>{{ title }}</span>
      </div>
      <div class="oy-table__header-set">
        <slot name="headerBtn"></slot>
        <slot name="headerDelete">
          <FIPopconfirmBtn
            v-if="deletable && (checkMode === 'check' || checkMode === 'radio')"
            style="margin-left: 12px"
            title="您是否确认删除选中数据吗？"
            buttonText="删除"
            beforePopText="请选择一条数据"
            :btn-binds="{ id: deleteId, border: true }"
            :isVisible="!!selectList.length"
            @confirm="deleteRow"
          >
          </FIPopconfirmBtn>
        </slot>
        <slot name="headerBtnRight"></slot>
        <slot name="headerSet">
          <div v-if="!settingConfig.hidden" class="set_box">
            <el-popover v-if="settingConfig.setting" placement="bottom" :width="274" trigger="click">
              <template #reference>
                <!-- <el-tooltip class="box-item" content="列设置" placement="top"> -->
                <i class="font_family icon-lieshezhi"></i>
                <!-- </el-tooltip> -->
              </template>
              <div class="set_box__setting common-scrollbar" v-if="columns.length">
                <div class="setting_header">
                  <el-checkbox
                    v-model="isColumnCheckAll"
                    :indeterminate="isIndeterminate"
                    @change="handleCheckAllChange"
                    class="setting_header__show"
                    label="列展示"
                  />
                  <el-checkbox class="setting_header__index" v-model="showRowNo" label="序列号" />
                  <div class="setting_header__btn" @click="initTableColumnSetting('delete')">重置</div>
                  <div class="setting_header__btn" @click="saveTableColumnSetting">保存</div>
                </div>
                <draggable v-model="cloneColumnList" itemKey="prop">
                  <template #item="{ element }">
                    <div class="drag-item">
                      <i class="font_family icon-yidonglie drag-item__icon"></i>
                      <div
                        class="drag-item__label"
                        @mouseenter="element.showFlexdIcon = true"
                        @mouseleave="element.showFlexdIcon = false"
                      >
                        <el-checkbox :label="element.label" v-model="element.isShow" />
                        <div v-if="element.showFlexdIcon" class="drag-item__flexd">
                          <el-tooltip class="box-item" effect="customized" content="固定在列首" placement="top">
                            <span>
                              <i
                                class="font_family icon-a-guanbizuocebiaoqianyegudingzailieshou"
                                @click="element.fixed = 'left'"
                              ></i>
                            </span>
                          </el-tooltip>
                          <el-tooltip class="box-item" effect="customized" content="固定在列尾" placement="top">
                            <span>
                              <i
                                class="font_family icon-a-guanbiyoucebiaoqianyegudingzailiewei"
                                @click="element.fixed = 'right'"
                              ></i>
                            </span>
                          </el-tooltip>
                        </div>
                      </div>
                    </div>
                  </template>
                </draggable>
              </div>
            </el-popover>
            <el-tooltip
              v-if="settingConfig.export"
              class="box-item"
              effect="customized"
              content="导出表格"
              placement="top"
            >
              <span @click="exportTableToExcel"><i class="font_family icon-daochubiaoge"></i></span>
            </el-tooltip>
            <el-tooltip
              v-if="settingConfig.locked"
              class="box-item"
              effect="customized"
              content="锁定数据"
              placement="top"
            >
              <span @click="lockToggle"
                ><i class="font_family icon-mima" :class="isTableLocked ? 'font_selected' : ''"></i
              ></span>
            </el-tooltip>
            <el-tooltip
              v-if="settingConfig.density"
              class="box-item"
              effect="customized"
              content="密度"
              placement="top"
            >
              <el-dropdown trigger="click">
                <i class="font_family icon-midu"></i>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item @click="tableLineHeightType = 0">默认</el-dropdown-item>
                    <el-dropdown-item @click="tableLineHeightType = 1">中等</el-dropdown-item>
                    <el-dropdown-item @click="tableLineHeightType = 2">紧凑</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </el-tooltip>

            <el-tooltip
              v-if="settingConfig.showSearch"
              class="box-item"
              effect="customized"
              content="显示/隐藏搜索"
              placement="top"
            >
              <span @click="hiddenSearch"><i class="font_family icon-chaxun"></i></span>
            </el-tooltip>
            <el-tooltip
              v-if="settingConfig.refresh"
              class="box-item"
              effect="customized"
              content="刷新列"
              placement="top"
            >
              <span @click="refreshColumn"><i class="font_family icon-shuaxinliebiao"></i></span>
            </el-tooltip>
          </div>
        </slot>
      </div>
    </div>
    <el-table
      v-if="cloneColumnList"
      v-loading="isLoading"
      class="oy-table__class"
      :class="`table-line__height-${tableLineHeightType}`"
      :data="cloneTableData"
      style="width: 100%"
      header-align="center"
      border
      @selection-change="handleSelectionChange"
      :row-class-name="rowClassName"
      :current-row-key="currentRowKey"
      v-bind="{ ...tableBinds, ...$attrs }"
      v-on="$attrs"
      ref="tableEl"
      :id="'exportTab' + id"
      @row-click="rowClick"
    >
      <el-table-column v-if="draggableRow" label="" width="70" align="center" fixed>
        <i class="font_family icon-yidonglie drag-row__icon"></i>
      </el-table-column>

      <!-- 复选框/单选框/序列号 -->
      <el-table-column
        v-if="cloneColumnList && checkMode === 'check'"
        type="selection"
        width="60"
        align="center"
        fixed
      />
      <el-table-column v-if="showRowNo" type="index" width="55" label="序号" align="center" />
      <el-table-column v-if="cloneColumnList && checkMode === 'radio'" align="center" fixed min-width="55" label="选择">
        <template #default="scope">
          <!-- 可以手动的修改label的值，从而控制选择哪一项 -->
          <!-- 注意：这里写 &nbsp 的目的是为了页面不显示内容，只显示单选操作 -->
          <el-radio
            class="radio"
            v-model="singleSelect"
            :label="scope.row[primaryKey]"
            @click="singleElection(scope.row)"
            >&nbsp;</el-radio
          >
        </template>
      </el-table-column>
      <!-- 主体内容 -->
      <template v-for="(item, index) in cloneColumnList" :key="item.prop">
        <slot :name="`${item.prop}-column`">
          <template v-if="item.prop != 'action' && item.isShow">
            <!-- 常规列 -->
            <el-table-column
              :prop="item.prop"
              :label="item.label"
              :width="item.width"
              :min-width="item.minWidth"
              :align="item.align ? item.align : 'center'"
              :filters="item.filters"
              :fixed="item.fixed"
              v-bind="{ ...item.columnBinds, ...$attrs }"
            >
              <template #header>
                <span class="common-font-bold14" :class="getRequiredStatus(item) ? 'required-star-class' : ''"
                  >{{ item.label }}
                  <div v-if="item.sortable" class="sort-icon-container" @click="changeSortableValue(item)">
                    <div class="sort-icon down" :class="item.sortValue === 'desc' ? 'down-active' : ''"></div>
                    <div class="sort-icon up" :class="item.sortValue === 'asc' ? 'up-active' : ''"></div>
                  </div>
                  <el-popover
                    v-if="item.filterable"
                    v-model:visible="item.showDynamicPop"
                    placement="bottom"
                    title=" "
                    :width="300"
                    trigger="click"
                  >
                    <template #reference>
                      <!-- 当列筛选有值，且点击搜索按钮后才标记有筛选条件 -->
                      <i
                        v-if="isColumnFillterHasValue(item)"
                        class="font_family icon-lieshaixuanyoujilu icon-filter icon-filter__selected"
                      ></i>
                      <i v-else class="font_family icon-lieshaixuan icon-filter"></i>
                    </template>
                    <Filter
                      :columnItem="item"
                      :options="item?.editConfig?.options"
                      :selectBinds="item?.editConfig?.selectBinds"
                      @filter-reset="filterReset(index)"
                      @column-filter-confirm="filterConfirm"
                    /> </el-popover
                ></span>
              </template>

              <template #default="scope">
                <slot :name="item.prop" :scope="scope">
                  <div v-if="!readonly && (!item.readonly || !scope.row[primaryKey] || !item.editable)">
                    <el-form
                      :model="cloneTableData[scope.$index]"
                      :rules="item.editConfig ? item.editConfig.rules : null"
                      @submit.prevent
                    >
                      <!-- 当前表格可以被编辑，且当前列被选中可以被编辑，并且处于非编辑状态，单击后变为可编辑状态 -->
                      <!-- cell 必填，校验为空时 -->
                      <el-tooltip
                        v-if="item.editType == 'input' && showRequredFn(scope.$index, scope.column.property)"
                        class="required-tooltip"
                        :content="showRequredMsg(scope.$index, scope.column.property)"
                      >
                        <el-form-item
                          :prop="item.prop"
                          label=""
                          :class="{
                            'edit-form-item': !item.currentEdit,
                            'edit-hover__class':
                              scope.row.isSelected &&
                              item.editable &&
                              (!item.currentEdit || (item.currentEdit && !scope.row.currentEdit)),
                          }"
                          @click="handleChangeEditCell(scope.$index, index, item)"
                        >
                          <div
                            v-if="
                              scope.row.isSelected &&
                              item.editable &&
                              (!item.currentEdit || (item.currentEdit && !scope.row.currentEdit))
                            "
                            :class="{
                              'common-text-ellipsis': !isTextWrap,
                              'cell-change__class': valueIsChanged(scope.row, scope.$index, index),
                            }"
                          >
                            <span v-if="item.editType == 'select'">
                              {{ valueToLabel(scope.row[item.prop], item?.editConfig?.options) }}
                            </span>
                            <!-- <el-tooltip
                              v-else-if="item.editType == 'input' && showRequredFn(scope.$index, scope.column.property)"
                              class="required-tooltip"
                              :content="showRequredMsg(scope.$index, scope.column.property)"
                            >
                              <el-input v-model="scope.row[item.prop]"></el-input>
                            </el-tooltip> -->

                            <span v-else> {{ scope.row[item.prop] }} </span>
                          </div>
                          <el-input
                            v-if="
                              (item.editType == 'input' || item.editType == null) &&
                              item.editable &&
                              scope.row.isSelected &&
                              scope.row.currentEdit &&
                              item.currentEdit
                            "
                            v-model="scope.row[scope.column.property]"
                            clearable
                            @change="onCellChange(scope.$index, index, scope)"
                            @input="onCellEdit(scope.$index, index, scope, 'input')"
                            @blur="onCellBlur(scope.$index, index, scope, 'input')"
                            :placeholder="'请输入' + item.label"
                            :ref="(el) => handleSetInputMap(el, `${item.prop}_${scope.$index}`)"
                          ></el-input>
                          <FISelect
                            v-if="
                              item.editType == 'select' &&
                              item.editable &&
                              scope.row.isSelected &&
                              scope.row.currentEdit &&
                              item.currentEdit
                            "
                            v-model="scope.row[scope.column.property]"
                            :options="item?.editConfig?.options"
                            :codeOption="item?.editConfig?.codeOption"
                            @change="onCellChange(scope.$index, index, scope)"
                            @eidt-change="onCellEdit(scope.$index, index, scope)"
                            :placeholder="'请选择'"
                          >
                            <!-- <el-option v-for="item in item.options" :key="item.value" :label="item.label" :value="item.value" /> -->
                          </FISelect>
                          <el-time-picker
                            v-if="
                              item.editType === 'time-picker' &&
                              item.editable &&
                              scope.row.isSelected &&
                              scope.row.currentEdit &&
                              item.currentEdit
                            "
                            value-format="HH:mm:ss"
                            v-model="scope.row[scope.column.property]"
                            placeholder="请选择"
                            clearable
                            @change="onCellChange(scope.$index, index, scope)"
                          />
                          <el-date-picker
                            v-if="
                              item.editType === 'date-picker' &&
                              item.editable &&
                              scope.row.isSelected &&
                              scope.row.currentEdit &&
                              item.currentEdit
                            "
                            v-model="scope.row[scope.column.property]"
                            @change="onCellChange(scope.$index, index, scope)"
                            placeholder="请选择"
                            clearable
                          >
                          </el-date-picker>
                          <span v-if="!item.editable && scope.row.isSelected"
                            ><el-tooltip class="tooltip" :content="scope.row[item.prop] || ''" effect="customized">
                              <span v-if="item.editType == 'select'">{{
                                valueToLabel(scope.row[item.prop], item?.editConfig?.options)
                              }}</span>
                              <span v-else>{{ scope.row[scope.column.property] }}</span>
                            </el-tooltip></span
                          >
                          <!-- 非选择可编辑状态下展示 -->
                          <div
                            v-if="item.editType != 'select' && !scope.row.isSelected"
                            :class="{
                              'common-text-ellipsis': !isTextWrap,
                              'cell-text__align-center': item.align === 'center',
                              'cell-text__align-right': item.align === 'right',
                              'cell-text__align-left': item.align === 'left',
                            }"
                          >
                            <el-tooltip class="tooltip" :content="scope.row[item.prop] || ''" effect="customized">
                              <span v-if="item.editType == 'time-picker' || item.editType == 'date-picker'">
                                {{
                                  scope.row[item.prop] && scope.row[item.prop] != ' '
                                    ? moment(scope.row[item.prop], 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss')
                                    : ''
                                }}
                              </span>
                              <div v-else>{{ scope.row[item.prop] }}</div>
                            </el-tooltip>
                          </div>

                          <!-- 特殊格式的正常情况展示，select -->
                          <div
                            v-if="item.editType == 'select' && !scope.row.isSelected"
                            :class="{
                              'common-text-ellipsis': !isTextWrap,
                              'cell-text__align-center': item.align === 'center',
                              'cell-text__align-right': item.align === 'right',
                              'cell-text__align-left': item.align === 'left',
                            }"
                          >
                            <el-tooltip
                              class="tooltip"
                              :content="valueToLabel(scope.row[item.prop], item?.editConfig?.options) || ''"
                              effect="customized"
                            >
                              {{ valueToLabel(scope.row[item.prop], item?.editConfig?.options) }}</el-tooltip
                            >
                          </div>
                        </el-form-item>
                      </el-tooltip>
                      <!-- 当前表格可以被编辑，且当前列被选中可以被编辑，并且处于非编辑状态，单击后变为可编辑状态 -->
                      <el-form-item
                        v-else
                        :prop="item.prop"
                        label=""
                        :class="{
                          'edit-form-item': !item.currentEdit,
                          'edit-hover__class':
                            scope.row.isSelected &&
                            item.editable &&
                            (!item.currentEdit || (item.currentEdit && !scope.row.currentEdit)),
                        }"
                        @click="handleChangeEditCell(scope.$index, index, item)"
                      >
                        <div
                          v-if="
                            scope.row.isSelected &&
                            item.editable &&
                            (!item.currentEdit || (item.currentEdit && !scope.row.currentEdit))
                          "
                          :class="{
                            'common-text-ellipsis': !isTextWrap,
                            'cell-change__class': valueIsChanged(scope.row, scope.$index, index),
                          }"
                        >
                          <span v-if="item.editType == 'select'">
                            {{ valueToLabel(scope.row[item.prop], item?.editConfig?.options) }}
                          </span>
                          <!-- <el-tooltip
                            v-else-if="item.editType == 'input' && showRequredFn(scope.$index, scope.column.property)"
                            class="required-tooltip"
                            :content="showRequredMsg(scope.$index, scope.column.property)"
                          >
                            <el-input v-model="scope.row[item.prop]"></el-input>
                          </el-tooltip> -->

                          <span v-else> {{ scope.row[item.prop] }} </span>
                        </div>
                        <el-input
                          v-if="
                            (item.editType == 'input' || item.editType == null) &&
                            item.editable &&
                            scope.row.isSelected &&
                            scope.row.currentEdit &&
                            item.currentEdit
                          "
                          v-model="scope.row[scope.column.property]"
                          clearable
                          @change="onCellChange(scope.$index, index, scope)"
                          @input="onCellEdit(scope.$index, index, scope, 'input')"
                          @blur="onCellBlur(scope.$index, index, scope, 'input')"
                          :placeholder="'请输入' + item.label"
                          :ref="(el) => handleSetInputMap(el, `${item.prop}_${scope.$index}`)"
                        ></el-input>
                        <FISelect
                          v-if="
                            item.editType == 'select' &&
                            item.editable &&
                            scope.row.isSelected &&
                            scope.row.currentEdit &&
                            item.currentEdit
                          "
                          v-model="scope.row[scope.column.property]"
                          :options="item?.editConfig?.options"
                          :codeOption="item?.editConfig?.codeOption"
                          @change="onCellChange(scope.$index, index, scope)"
                          @eidt-change="onCellEdit(scope.$index, index, scope)"
                          :placeholder="'请选择'"
                        >
                          <!-- <el-option v-for="item in item.options" :key="item.value" :label="item.label" :value="item.value" /> -->
                        </FISelect>
                        <el-time-picker
                          v-if="
                            item.editType === 'time-picker' &&
                            item.editable &&
                            scope.row.isSelected &&
                            scope.row.currentEdit &&
                            item.currentEdit
                          "
                          value-format="HH:mm:ss"
                          v-model="scope.row[scope.column.property]"
                          placeholder="请选择"
                          clearable
                          @change="onCellChange(scope.$index, index, scope)"
                        />
                        <el-date-picker
                          v-if="
                            item.editType === 'date-picker' &&
                            item.editable &&
                            scope.row.isSelected &&
                            scope.row.currentEdit &&
                            item.currentEdit
                          "
                          v-model="scope.row[scope.column.property]"
                          clearable
                          @change="onCellChange(scope.$index, index, scope)"
                          placeholder="请选择"
                        >
                        </el-date-picker>
                        <span v-if="!item.editable && scope.row.isSelected"
                          ><el-tooltip class="tooltip" :content="scope.row[item.prop] || ''" effect="customized">
                            <span v-if="item.editType == 'select'">{{
                              valueToLabel(scope.row[item.prop], item?.editConfig?.options)
                            }}</span>
                            <span v-else-if="item.editType === 'time-picker'">{{
                              convertTimestampToDate(scope.row[scope.column.property])
                            }}</span>
                            <span v-else-if="item.editType != 'select'">{{ scope.row[scope.column.property] }}</span>
                          </el-tooltip></span
                        >
                        <!-- 非选择可编辑状态下展示 -->
                        <div
                          v-if="item.editType != 'select' && !scope.row.isSelected"
                          :class="{
                            'common-text-ellipsis': !isTextWrap,
                            'cell-text__align-center': item.align === 'center',
                            'cell-text__align-right': item.align === 'right',
                            'cell-text__align-left': item.align === 'left',
                          }"
                        >
                          <el-tooltip class="tooltip" :content="scope.row[item.prop] || ''" effect="customized">
                            <span v-if="item.editType == 'time-picker' || item.editType == 'date-picker'">
                              {{
                                scope.row[item.prop] && scope.row[item.prop] != ' '
                                  ? moment(scope.row[item.prop], 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss')
                                  : ''
                              }}
                            </span>
                            <div v-else>{{ scope.row[item.prop] }}</div>
                          </el-tooltip>
                        </div>

                        <!-- 特殊格式的正常情况展示，select -->
                        <div
                          v-if="item.editType == 'select' && !scope.row.isSelected"
                          :class="{
                            'common-text-ellipsis': !isTextWrap,
                            'cell-text__align-center': item.align === 'center',
                            'cell-text__align-right': item.align === 'right',
                            'cell-text__align-left': item.align === 'left',
                          }"
                        >
                          <el-tooltip
                            class="tooltip"
                            :content="valueToLabel(scope.row[item.prop], item?.editConfig?.options) || ''"
                            effect="customized"
                          >
                            {{ valueToLabel(scope.row[item.prop], item?.editConfig?.options) }}</el-tooltip
                          >
                        </div>
                      </el-form-item>
                    </el-form>
                  </div>
                  <div v-else>
                    <el-tooltip class="tooltip" :content="scope.row[item.prop] || ''" effect="customized">
                      <!-- 注意Value to lable 自定义赋值 -->
                      <span v-if="item.editType == 'select'">
                        {{ valueToLabel(scope.row[item.prop], item?.editConfig?.options) }}
                      </span>
                      <span v-if="item.editType == 'time-picker' || item.editType == 'date-picker'">
                        {{
                          scope.row[item.prop] && scope.row[item.prop] != ' '
                            ? moment(scope.row[item.prop], 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss')
                            : ''
                        }}
                      </span>
                      <div v-else :class="isTextWrap ? '' : 'common-text-ellipsis'">{{ scope.row[item.prop] }}</div>
                    </el-tooltip>
                  </div>
                </slot>
              </template>
            </el-table-column>
          </template>
          <!-- 操作列 -->
          <el-table-column
            v-if="item.prop == 'action' && item.isShow"
            :label="item.label"
            :width="item.width || 80"
            :min-width="item.minWidth"
            :fixed="item.fixed || 'right'"
            :align="item.align ? item.align : 'center'"
          >
            <template #default="scope">
              <slot name="action" :scope="scope">
                <el-dropdown
                  v-if="
                    item.actionConfig ||
                    (item.isCustomAction && scope.row.dynamicActionConfig && scope.row.dynamicActionConfig.length > 0)
                  "
                  class="cell-action"
                  :disabled="scope.row[primaryKey] || scope.row.value ? false : true"
                >
                  <!-- <div><FIButton class="el-dropdown-link" text>...</FIButton></div> -->

                  <div class="action-dropdown-link">...</div>
                  <template #dropdown>
                    <el-dropdown-menu v-if="!item.isCustomAction">
                      <template v-if="Array.isArray(item.actionConfig)">
                        <el-dropdown-item
                          v-for="(chidBtn, index) in item.actionConfig"
                          :key="chidBtn + index"
                          @click="handleAction(chidBtn, scope.row)"
                        >
                          <FIButton v-if="chidBtn.id" :id="chidBtn.id" text v-bind="{ ...chidBtn.btnBinds }"></FIButton>
                          <FIButton v-if="!chidBtn.id && chidBtn.label" text v-bind="{ ...chidBtn.btnBinds }">{{
                            chidBtn.label
                          }}</FIButton>
                        </el-dropdown-item></template
                      >
                    </el-dropdown-menu>
                    <el-dropdown-menu v-else>
                      <template v-if="Array.isArray(scope.row.dynamicActionConfig)">
                        <template v-for="(chidBtn, index) in scope.row.dynamicActionConfig" :key="chidBtn + index">
                          <el-dropdown-item v-if="!chidBtn.hidden" @click="handleAction(chidBtn, scope.row)">
                            <FIButton
                              v-if="chidBtn.id"
                              :id="chidBtn.id"
                              text
                              v-bind="{ ...chidBtn.btnBinds }"
                            ></FIButton>
                            <FIButton v-if="!chidBtn.id && chidBtn.label" text v-bind="{ ...chidBtn.btnBinds }">{{
                              chidBtn.label
                            }}</FIButton>
                          </el-dropdown-item>
                        </template>
                      </template>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </slot>
            </template>
          </el-table-column>
        </slot>
      </template>
      <!-- </template> -->
      <slot></slot>
      <template #empty><slot name="empty"></slot></template>
    </el-table>
    <!-- 当表可以编辑，并且可以新增行编辑 同时满足时可以新增行 -->
    <FIButton
      v-if="!readonly && insertable"
      :id="insertBtn"
      prefixIcon="icon-xinzeng"
      class="insert-btn__class"
      customType
      @click.stop="onAddRow"
      >添加一行数据</FIButton
    >
    <FIPagination
      v-if="showPageBar && !isLoading"
      class="oy-table__page"
      v-bind="{ ...pageConfig }"
      :current-page="pageConfig.currentPage"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></FIPagination>
    <add-model
      v-if="showSaveModel"
      :showSaveBar="showSaveBar"
      :selectedNum="selectList.length"
      :saveBtn="saveBtn"
      @row-add-cancel="addRowCancel"
      @row-add-save="addRowSave"
    ></add-model>
  </div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, watch, nextTick, PropType } from 'vue'
import FIPagination from '@/components/FIPagination.vue'
import FIPopconfirmBtn from '@/components/FIPopconfirmBtn.vue'
import draggable from 'vuedraggable'
import Sortable from 'sortablejs'
import Filter from './filter.vue'
import addModel from './addModel.vue'
import FISelect from '@/components/FISelect/index.vue'
import FIButton from '@/components/FIButton.vue'
import LocalCache from '@/utils/cache'
import { valueToLabel, getButtonInfoById, clientColumnFilterData } from '@/utils/common.js'
import { apiRequestPost } from '@/api/globalApi.js'
import OMS from '@/utils/exportTools'
import { cloneDeep } from 'lodash'
import moment from 'moment'
import type { SettingConfigType, PageConfig } from './FITable'
import { ElTable } from 'element-plus'
import { useTableStore, removePrefixesFn } from '@/stores/table'
import { useRoute } from 'vue-router'
import { useMessage, useMessageBox } from '@/hooks/message'

const route = useRoute()
const props = defineProps({
  id: {
    type: String,
    default: '',
    required: true,
  },
  // 是否绑定搜索区域表单
  isBindSearch: {
    type: Boolean,
    default: true,
  },
  // 查询接口, 无绑定搜索区域，默认查询queryApi，如果绑定搜索区域，则自定义，跟搜索区域表单查询方法一致，定义通用搜索方法
  queryApi: {
    type: String,
    default: '',
  },
  // table显示的数据
  data: {
    type: Array,
    default: () => {
      return []
    },
  },
  // 是否显示表格头部工具栏，true/false
  showToolbar: {
    type: Boolean,
    default: true,
  },
  isLoading: {
    type: Boolean,
    default: false,
  },
  // readonly：是否只读表格，true只读/false列可编辑，默认true
  readonly: {
    type: Boolean,
    default: true,
  },
  // checkMode：表格数据复选框选择模式，单选-radio/多选-checkbox, 默认 空值，无多选，单选
  checkMode: {
    type: String,
    default: 'check',
  },
  // 表格高度 默认为自动高度。 如果 height 为 number 类型，单位 px；如果 height 为 string 类型，则这个高度会设置为 Table 的 style.height 的值，Table 的高度会受控于外部样式
  // height: {
  //   type: [String, Number],
  //   default: '',
  // },
  // 是否通过点击row选中当前行，默认false
  rowSelectable: {
    type: Boolean,
    default: false,
  },
  // table数据展示对应行 id, 可不填
  primaryKey: {
    type: String,
    default: 'id',
  },
  // 是否显示序列号列，true/false
  rowNo: {
    type: Boolean,
    default: false,
  },
  // 头部左侧表名
  title: {
    type: String,
    default: '',
  },
  // 是否显示表设置
  showSetting: {
    type: Boolean,
    default: true,
  },
  // 表头工具栏单个选项显示，隐藏配置
  settingConfig: {
    type: Object as PropType<SettingConfigType>,
    default: () => {
      return {
        setting: true, // 设置
        export: true, // 导出数据
        locked: true, // 锁定
        density: true, // 密度
        showSearch: true, // 是否显示绑定搜索表单
        refresh: true, // 是否显示刷新
        hidden: false, // 隐藏操作栏上所有内容
      }
    },
  },
  // 文案是否多行显示，单行文案过长...显示，并hover
  isTextWrap: {
    type: Boolean,
    default: false,
  },
  // 是否允许新增一行数据
  insertable: {
    type: Boolean,
    default: true,
  },
  // 是否删除
  deletable: {
    type: Boolean,
    default: false,
  },
  deleteId: {
    type: String,
    default: 'delete',
  },
  // 是否锁定，锁定后本地筛选
  // locked: {
  //   type: Boolean,
  //   default: false,
  // },
  // 是否在表尾显示合计行  如果自定义表尾总计需要配套使用函数 :summary-method="getSummaries"
  showSummary: {
    type: Boolean,
    default: false,
  },
  // 显示摘要行第一列的文本
  sumText: {
    type: String,
    default: '小计',
  },
  // 分页配置对象，参数参照el-pagination官方文档
  pageConfig: {
    type: Object as PropType<PageConfig>,
    default: () => {
      return {
        currentPage: 1,
        // pageSize: 50,
        // pageSizes: [50, 100, 200],
        pageSize: 10,
        pageSizes: [10, 20, 50, 100],
      }
    },
  },
  // 当前页码
  currentPage: {
    type: Number,
    default: 1,
  },
  // 当前每页数量
  pageSize: {
    type: Number,
    default: 3,
  },
  pageSizes: {
    type: Array as PropType<number[]>,
    default: () => [3, 100, 200],
  },
  // 表数据总计
  totalNum: {
    type: Number,
    default: 0,
  },
  // table 原生所带属性
  tableBinds: {
    type: Object,
    default: () => {
      return {
        //   highlightCurrentRow: true,
        //   showOverflowTooltip: { effect: 'customized' }, // 溢出 tooltip 的选项
        //   showSummary: true, // 是否在表尾显示合计行
        //   sumText: '小计', // 显示摘要行第一列的文本
      }
    },
  },
  /** 表头数据
   * label: 显示的标题 string,
   * prop：字段名称 对应列内容的字段名，也可以使用 property属性
   * width
   * sortable 是否允许列排序
   * */
  columns: {
    type: Array,
    default: () => {
      return []
    },
  },
  // 是否使用底部保存弹窗
  showSaveModel: {
    type: Boolean,
    default: true,
  },
  // 是否显示page分页组件
  showPageBar: {
    type: Boolean,
    default: true,
  },
  // 保存成功按钮状态，默认不展示底部保存，取消按钮
  saveSuccessful: {
    type: Boolean,
    default: false,
  },
  // 表格新增行按钮id
  insertBtn: {
    type: String,
    default: 'insert',
  },
  // 表格修改新增保存按钮id
  saveBtn: {
    type: String,
    default: 'save',
  },
  draggableRow: {
    type: Boolean,
    default: false,
  },
})
const emit = defineEmits([
  'search-toggle',
  'table-refresh',
  'selection-change',
  'row-add',
  'column-filter-confirm',
  'filter-reset',
  'row-add-cancel',
  'row-add-save',
  'update:columns',
  'update:data',
  'change-sort',
  'size-change',
  'current-page-change',
  'cell-set-value',
  'on-cell-change',
  'on-cell-edit',
  'action-click',
  'on-cell-blur',
  'row-click',
  'row-delete',
  'save-validate-errors', // 保存校验错误集合
])
const tableStore = useTableStore()

const showSearch = ref(true)
const hiddenSearch = () => {
  showSearch.value = !showSearch.value
  tableStore.updateSearchFormStatus(`${props.id}_search_show`, showSearch.value)
  emit('search-toggle')
}
const refreshColumn = () => {
  emit('table-refresh')
}
const handleSizeChange = (e) => {
  emit('size-change', e)
}
const handleCurrentChange = (e) => {
  emit('current-page-change', e)
}
//转为时间格式
const convertTimestampToDate = (timestamp) => {
  console.log(timestamp, 'timestamp')
  // 将时间戳拆分成各个部分
  if (timestamp) {
    const year = timestamp.substring(0, 4)
    const month = timestamp.substring(4, 6)
    const day = timestamp.substring(6, 8)
    if (timestamp.substring(8, 10)) {
      const hour = timestamp.substring(8, 10)
      const minute = timestamp.substring(10, 12)
      const second = timestamp.substring(12, 14)
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`
    } else {
      // 格式化成目标时间格式
      return `${year}-${month}-${day}`
    }
  }
}
const isTableLocked = ref(false)
// 最后编辑单元格所在行索引
const lastEditCellRowIndex = ref(0)
// 自定义筛选查询
const filterConfirm = (filterData) => {
  if (!isUseQueryApi.value) {
    // 如果table锁定，则客户端筛选, 每次传值都是全部初始值props.data
    if (isTableLocked.value) {
      cloneTableData.value = clientColumnFilterData(cloneDeep(props.data), filterData.columnItem)
    } else {
      // 只有当非客户端筛选时才传递
      // emit('column-filter-confirm', filterData)
      // let selectedProp = e.columnItem.prop
      // Array.isArray(columns) &&
      //   columns.forEach((item: any) => {
      //     if (item?.prop == selectedProp) {
      //       item.modelValue = e.columnItem?.modelValue
      //       item.showHighSearch = true
      //     }
      //   })
      emit('table-refresh', 'filter', cloneColumnList.value)
    }
  } else {
    // 如果是table无绑定搜索区域，table自动查询，则无视table锁定，都走接口查询
    searchFn()
  }
  filterData.columnItem.showDynamicPop = false
}
// 清除自定义筛选条件
const filterReset = (index) => {
  cloneColumnList.value[index].showHighSearch = false
  cloneColumnList.value[index].showDynamicPop = false
  // emit('filter-reset', cloneColumnList.value[index])
  emit('table-refresh', 'filter', cloneColumnList.value)
  // cloneColumnList[index].configFilter.valueLike = ''
}
// 自定义排序事件
const changeSortableValue = (e) => {
  const ops = e?.sortValue || ''
  // 点击轮换排序，无排序-->升序-->降序-->无排序
  if (!ops) {
    e.sortValue = 'asc'
  } else if (ops === 'asc') {
    e.sortValue = 'desc'
  } else {
    e.sortValue = ''
  }
  if (isTableLocked.value) {
    // 前端自行排序 prop: string, order: string
    let tempOrderBy = e.sortValue ? e.sortValue + 'ending' : ''
    tableEl.value.sort(e.prop, tempOrderBy)
    // cloneTableData.value = clientFilter(props.queryData, cloneTableData.value)
  } else {
    // 只有当非客户端筛选时才传递
    emit('table-refresh', 'sort', cloneColumnList.value)
    // emit('change-sort', 'sort', cloneColumnList.value)
  }
}

// 创建一个深拷贝的ref数组
const cloneTableData = ref<any[]>([])
// 在组件初始化时复制数据
cloneTableData.value = cloneDeep(props.data)
// 监听父组件传递的 tableData prop 的变化
watch(
  () => props.data,
  (newTableData) => {
    // 深拷贝新的 props.data 到 cloneTableData
    cloneTableData.value = cloneDeep(newTableData)
  },
  { immediate: true, deep: true }
)

const selectList = ref<any[]>([])
const singleSelect = ref('')

// 列选中回调事件
const handleSelectionChange = (val) => {
  selectList.value = val
  emit('selection-change', val)
  // multipleSelection.value = val
}
//单选某行
const rowClick = (val) => {
  emit('row-click', val)
  if (props.rowSelectable) {
    singleElection(val)
  }
}
const singleElection = (row) => {
  singleSelect.value = row[props.primaryKey]
  selectList.value = cloneTableData.value.filter((item) => item[props.primaryKey] === row[props.primaryKey])
  emit('selection-change', selectList.value)
}

// 多选选中行高亮
const rowClassName = ({ row, rowIndex }) => {
  if (selectList.value?.includes(row)) {
    cloneTableData.value[rowIndex].isSelected = true
    return 'current-row'
  } else {
    cloneTableData.value[rowIndex].isSelected = false
  }
}
// table密度 0: 默认 1：中等 2：紧凑
const tableLineHeightType = ref(0)
const cloneColumnList = ref<any[]>([])
// const cloneColumnList = cloneDeep(props.columns)
cloneColumnList.value = cloneDeep(props.columns)
// 监听父组件传递的 tableData prop 的变化
// 监听 cloneColumnList 的变化
watch(
  () => cloneColumnList.value,
  (newValue, oldValue) => {
    if (oldValue) {
      const userData = LocalCache.getCache('user')
      const userId = userData.userId
      LocalCache.setCache(`${userId}-${route.path}-${removePrefixesFn(props.id)}-columns`, newValue)
      // console.log('--cloneColumnList---', cloneColumnList.value)
    }
    emit('update:columns', newValue)
  },
  { deep: true } // 开启深度监听，因为数组或对象内部属性的改变浅层监听可能无法捕获
)

// 是否展示所有column
const isColumnCheckAll = ref(true)
// 设置checkbox不确定状态，仅负责样式控制
const isIndeterminate = computed(() => {
  const checkedList = cloneColumnList.value.filter((item) => item.isShow === true)
  if (checkedList.length === cloneColumnList.value.length) {
    // eslint-disable-next-line vue/no-side-effects-in-computed-properties
    isColumnCheckAll.value = true
    return false
  } else if (checkedList.length === 0) {
    // eslint-disable-next-line vue/no-side-effects-in-computed-properties
    isColumnCheckAll.value = false
    return false
  } else {
    return true
  }
  // return checkedList.length !== cloneColumnList.value.length && checkedList.length > 0
})

// 是否展示row index
const showRowNo = ref(props.rowNo)
// 是否展示 保存 按钮（当有选中值时展示）
const showSaveBar = computed(() => {
  return !!selectList.value.length
})
// 监听修改状态，当修改状态为成功时把选中list清空，保存按钮也会同步隐藏
watch(
  () => props.saveSuccessful,
  (newValue) => {
    if (newValue) {
      selectList.value = []
    }
  }
)
const handleCheckAllChange = (val) => {
  if (val) {
    // initTableColumnSetting()
    // isIndeterminate.value = false
    cloneColumnList.value.forEach((element) => {
      element.isShow = true
    })
  } else {
    cloneColumnList.value.forEach((element) => {
      element.isShow = false
    })
  }
}
const handleColumnChange = (value) => {
  const checkedCount = value.length
  isColumnCheckAll.value = checkedCount === cloneColumnList.value.length
  // isIndeterminate.value = checkedCount > 0 && checkedCount < cloneColumnList.value.length
}
// 初始化table表头
const initTableColumnSetting = (type = '') => {
  showRowNo.value = false
  isColumnCheckAll.value = true
  // isIndeterminate.value = true
  // cloneColumnList.value = JSON.parse(JSON.stringify(props.columns))
  cloneColumnList.value.forEach((element) => {
    element.isShow = true
    element.showFlexdIcon = false
    element.fixed = element.label === '操作' ? 'right' : null
  })
  if (type === 'delete') {
    deleteTableConfig()
  }
}
// 删除列设置模版
const deleteTableConfig = () => {
  apiRequestPost('/rm2/tableConfig/delete', { tableId: route.path + ':' + props.id })
    .then((res) => {
      if (res.data.success) {
        useMessage().success('重置成功')
      }
    })
    .catch((error) => {
      // 处理错误
    })
}
// 保存 table 设置模版
const saveTableColumnSetting = () => {
  // 接口参数 {
  //   userid: '',
  //   tableId: '',
  //   type: 'tableSetting',
  //   columnList: cloneColumnList.value
  // }
  apiRequestPost('/rm2/tableConfig/insert', {
    tableId: route.path + ':' + props.id,
    configValue: JSON.stringify({
      cloneData: cloneColumnList.value,
      showRowNo: showRowNo.value,
    }),
  })
    .then((res) => {
      if (res.data.data) {
        useMessage().success('保存成功')
      } else {
        useMessage().error('保存失败，请稍后再试.')
      }
    })
    .catch((error) => {
      // 处理错误
    })
  // LocalCache.setCache(`${props.tableId}-tableSetting`, JSON.stringify(cloneColumnList.value))
  // ElMessage('保存成功.')
}
// 单个编辑事件 -- 只有Input，Select 可以触发columnIndex
const onCellEdit = (rowIndex, columnIndex, scope, type) => {
  emit('on-cell-edit', rowIndex, columnIndex, scope)
  lastEditCellRowIndex.value = rowIndex
}
// 编辑修改对应的数组，[rowIndex, columnIndex]
const changeValueIndexs = ref([])
const onCellChange = (rowIndex, columnIndex, scope) => {
  emit('on-cell-change', rowIndex, columnIndex, scope)
  lastEditCellRowIndex.value = rowIndex
  // 目前只比对了修改前后值，是否需要跟 最初 的值比对，看是否有修改，
  const tempIndex = `${rowIndex}-${columnIndex}`
  if (!changeValueIndexs.value.includes(tempIndex)) {
    changeValueIndexs.value.push(tempIndex)
  }
}

// 单个cell失焦事件 --
const requiredList = ref(<any>[])

const onCellBlur = async (rowIndex, columnIndex, scope, type) => {
  emit('on-cell-blur', rowIndex, columnIndex, scope)
  // 确保 scope.column 存在
  if (!scope.column) return
  // 获取当前列配置
  // const currentColumn = cloneColumnList.value[scope.column.property]
  const currentColumn = cloneColumnList.value.find((item) => item.prop == scope.column.property)
  // requiredList.value = requiredList.value.filter((item) => item.id !== keyId)
  // 如果是必填列，则进行验证
  if (currentColumn?.required) {
    const cellValue = scope.row[scope.column.property]
    const keyId = `${rowIndex}-${scope.column.property}`
    // 根据cell值是否为空决定添加或移除校验提示
    if (cellValue === '' || cellValue === undefined || cellValue === null) {
      addRequriedListFn(scope.$index, currentColumn)
    } else {
      await nextTick()
      // 移除该行的校验提示
      if (Array.isArray(requiredList.value) && requiredList.value.length > 0) {
        let index = requiredList.value.findIndex((item) => item.keyId === keyId)
        requiredList.value.splice(index, 1)
      }
      // 移除该行的校验提示 --这行代码会造成死循环，为什么
      // requiredList.value = requiredList.value.filter((item) => item.id !== keyId)
    }
  }
  // 日志输出保持原样，但通常生产环境中应避免使用过多console.log
  console.log('cloneTableData-----0003', requiredList.value, scope.column.property, currentColumn)
}
// 初始化必填项，如果必填项为空，则添加必填项
const initRequiredList = () => {
  Array.isArray(selectList.value) &&
    selectList.value.forEach((item, index) => {
      // 根据 Item 主键id 来计算出rowIndex, 如果主键id不存在，则为新增列，遍历新增列，给rowIndex赋值
      let rowIndex = 0
      if (item[props.primaryKey]) {
        rowIndex = cloneTableData.value.findIndex((child) => child[props.primaryKey] === item[props.primaryKey])
        cloneColumnList.value.forEach((columnChid) => {
          addRequriedListFn(rowIndex, columnChid)
        })
      }
    })
}
const addRequriedListFn = (rowIndex, columnItem) => {
  // 如果是必填列，则进行验证
  if (columnItem?.required) {
    // const cellValue = scope.row[scope.column.property]
    // const keyId = `${rowIndex}-${scope.column.property}`
    const cellValue = cloneTableData.value[rowIndex][columnItem.prop]
    const keyId = `${rowIndex}-${columnItem.prop}`

    // 根据cell值是否为空决定添加或移除校验提示
    if (cellValue === '' || cellValue === undefined || cellValue === null) {
      // 使用数组和 findIndex 来避免重复添加
      const index = requiredList.value.findIndex((item) => item.id === keyId)
      if (index === -1) {
        let obj = {
          id: keyId,
          prop: columnItem.prop,
          rowIndex: rowIndex,
          // columnIndex: columnIndex,
          showRequired: true,
          requiredMsg: '必填项',
        }
        requiredList.value.push(obj)
      } else {
        // 如果已存在则不再重复添加，使用已存在的校验
      }
    } else {
      // 移除该行的校验提示
      requiredList.value = requiredList.value.filter((item) => item.id !== keyId)
    }
  }
  // console.log('addRequriedListFn-----', requiredList.value)
}
const showRequredFn = (rowIndex, columnProp) => {
  const keyId = `${rowIndex}-${columnProp}`
  return requiredList.value.find((item) => item.id === keyId)
}
const showRequredMsg = (rowIndex, columnProp) => {
  const keyId = `${rowIndex}-${columnProp}`
  // 直接查找匹配的对象并返回其requiredMsg，若不存在则返回默认值
  const requiredMsg = requiredList.value.find((item) => item.id === keyId)?.requiredMsg ?? '必填项'

  console.log('=======', requiredMsg)
  return requiredMsg
}
watch(
  () => selectList.value,
  (newData) => {
    console.log('requiredList.value------', newData)
    if (newData.length > 0) {
      // 如果selectList.value有值，则初始化requiredList.value
      initRequiredList()
    } else {
      // 如果selectList.value为空，则清空requiredList.value
      requiredList.value = []
    }
  },
  { deep: true }
)

// 判断当前行是否被修改过, 只计算被选中行
const valueIsChanged = (row, rowIndex, columnIndex) => {
  if (row.isSelected && changeValueIndexs.value.length > 0) {
    let temp = changeValueIndexs.value.find((item) => item == `${rowIndex}-${columnIndex}`)
    return temp
  }
}
const onAddRow = async () => {
  // 如果有选中行，新增则默认复制默认行数据
  if (selectList.value.length) {
    // 复制只复制已有数据，新增赋值的对象不再重新复制一遍

    useMessageBox()
      .confirm(`${selectList.value.length} 条记录被选中，将它们复制为新记录吗？`, '提示')
      .then(() => {
        //确定中要进行的操作
        // cloneTableData.value = cloneTableData.value.filter((item) => item[props.primaryKey] !== '')
        // 如果是单选，则新增复制只能增加一行，并选中这一行
        if (props.checkMode == 'radio') {
          if (!singleSelect.value) {
            ElMessage.warning('单选只能新增一行')
            return
          }
          singleSelect.value = ''
          cloneTableData.value = cloneTableData.value.filter((item) => item[props.primaryKey] !== '')
        }
        Array.isArray(selectList.value) &&
          selectList.value.forEach((item) => {
            const newItem = cloneDeep(item)
            // 新增复制时把rowId 置空
            if (item[props.primaryKey]) {
              newItem[props.primaryKey] = ''
            }
            // 遍历不可编辑属性数组，将新项目的对应属性值置空
            cloneColumnList.value.forEach((column) => {
              if (!column?.editable) {
                newItem[column?.prop] = ''
              }
            })
            // 新增列添加标识： _isNew:  1 新的,   空, 其他任何值,都不是新的
            newItem._isNew = 1
            cloneTableData.value.push(newItem)
            selectList.value.push(newItem)
            if (props.checkMode == 'check') {
              tableEl.value.toggleRowSelection(newItem, true)
            }
          })
        emit('row-add')
      })
      .catch(() => {
        //取消操作
        onAddEmptyRow()
        emit('row-add')
      })
  } else {
    // 新增一行空数据
    onAddEmptyRow()
    emit('row-add')
  }
}
// 新增一行空数据
const onAddEmptyRow = async () => {
  const newRow = cloneColumnList.value.reduce(
    (obj, item) => ({
      ...obj,
      ...(item.hasOwnProperty('prop') && { [item.prop]: '' }),
      // isSelected: true,
    }),
    {}
  )
  // 新增列添加标识： _isNew:  1 新的,   空, 其他任何值,都不是新的
  newRow._isNew = 1
  selectList.value.push(newRow)
  cloneTableData.value.push(newRow)
  await nextTick()
  tableEl.value.toggleRowSelection(newRow, true)
}
const addRowCancel = () => {
  selectList.value = []
  // 初始化列表
  cloneTableData.value = cloneDeep(props.data)

  // tableEl.value.clearSelection()
  emit('row-add-cancel')
}
const addRowSave = () => {
  saveValidate()
    ?.then(() => {
      emit('row-add-save', selectList.value)
    })
    .catch((err) => {
      useMessage().error(err.message)
    })
}
const deleteRow = () => {
  // 如果删除的是新增的，则前端删除
  let isOnlyNew = true
  if (selectList.value.length) {
    selectList.value.forEach((item) => {
      if (item._isNew) {
        // const index = cloneTableData.value.findIndex((e) => e[props.primaryKey] === item[props.primaryKey])
        const index = cloneTableData.value.findIndex((e) => e == item)
        if (index !== -1) {
          cloneTableData.value.splice(index, 1)
        }
      } else {
        isOnlyNew = false
      }
    })
  }
  if (!isOnlyNew) {
    emit('row-delete', selectList.value)
  }
}
watch(
  () => showSaveBar.value,
  (newTableData) => {
    if (!newTableData) {
      // 如果点击取消按钮，则把新增的Row取消掉
      cloneTableData.value = cloneTableData.value.filter((item) => item[props.primaryKey] !== '')
      if (props.checkMode == 'radio') {
        singleSelect.value = ''
      } else {
        // tableEl.value.clearSelection()
      }
    }
  }
)
// 动态ref对象
const inputRefs = ref({})
const handleSetInputMap = (el, item) => {
  if (el) {
    inputRefs.value[`inputRef_${item}`] = el
    // 最后一个点击的聚焦
    // el.focus()
    console.log('el', el)
  }
}

const handleChangeEditCell = (rowIndex, columnIndex, columnItem) => {
  // 当当前列不可编辑，则return
  if (columnItem.editable != null && !columnItem.editable) return
  cloneTableData.value.forEach((e, index) => {
    if (rowIndex === index) {
      e.currentEdit = true
    } else {
      e.currentEdit = false
    }
  })
  cloneColumnList.value.forEach((e, index) => {
    if (columnIndex === index) {
      e.currentEdit = true
    } else {
      e.currentEdit = false
    }
  })
  // 只有点击当前列时才聚焦
  setTimeout(() => {
    const item = `${columnItem.prop}_${rowIndex}`
    if (inputRefs.value[`inputRef_${item}`]) {
      inputRefs.value[`inputRef_${item}`].focus()
    }
  })
}
const handlePopoverClick = (event) => {
  // 检查点击是否在 Filter 组件或其子元素上
  if (event.target.closest('.filter-component-class-name')) {
    event.stopPropagation()
    event.preventDefault()
  }
}
// 获取form ref
const formRef = ref({})
// 动态ref
const handleRef = (el, scope, item) => {
  if (el) {
    formRef.value[`formRef-${scope.$index}-${item.prop || scope.column.property}`] = el
  }
}
// 单元格编辑是否存在校验
const isEditRules = computed(() => {
  return props.columns.some((item) => item?.editConfig?.rules)
})

// const tableEl = ref(null)
const tableEl = ref<InstanceType<typeof ElTable> | null>(null)

const exportTableToExcel = (fileName = props.title) => {
  let hiddenRows: number[] = []
  if (props.checkMode === 'check' || props.checkMode === 'radio') {
    hiddenRows = [0]
  }
  OMS.downLoadXlsx({
    dom: 'exportTab' + props.id,
    name: fileName + 'excel',
    ColumnWdth: [20, 20, 35],
    hiddenIndexs: hiddenRows,
  })
  // 数据埋点
  const userData = LocalCache.getCache('user')
  const obj = {
    tableId: route.path + ':' + props.id,
    action: 'export',
    herf: window.location.href,
    userId: userData?.loginName,
    userName: userData?.userName,
  }
  apiRequestPost('/userAction/log', obj).then((res) => {})
}
// 锁定数据
const lockToggle = () => {
  isTableLocked.value = !isTableLocked.value
}
// const filterStatus = computed(() => {
//   return cloneTableData.value.map((item) => isColumnFillterHasValue(item))
// })
const isColumnFillterHasValue = (item) => {
  // if (!item.filterable) return
  // console.log('0000000000', item)
  const objectType = Object.prototype.toString.call(item.modelValue)
  if (objectType === '[object Object]') {
    // 对象类型，检查对象属性是否有值
    return (
      item.showHighSearch &&
      Object.values(item.modelValue).some(
        (value) => value !== '' && value !== null && value !== undefined && value !== false
      )
    )
  } else if (Array.isArray(item.modelValue)) {
    // 数组类型，检查数组长度是否大于0以及是否显示高级搜索
    return item.modelValue.length > 0 && item.showHighSearch
  } else {
    // 其他类型（假设是非空字符串或数字等基本类型）
    return !!item.modelValue && item.showHighSearch
  }
}
// 获取列设置模版
const getTableConfig = () => {
  apiRequestPost('/rm2/tableConfig/get', { tableId: route.path + ':' + props.id })
    .then((res) => {
      if (res.data.success && res.data.data) {
        let configData = res.data.data.configValue && JSON.parse(res.data.data.configValue)
        if (configData.cloneData) cloneColumnList.value = configData.cloneData
        showRowNo.value = configData?.showRowNo
      }
    })
    .catch((error) => {
      // 处理错误
    })
}

// ************ 以下为 table内自动请求数据相关 ********************************
// 是否通过配置URL，table内自动查询
const isUseQueryApi = computed(() => {
  return !props.isBindSearch && props.queryApi
})
const isTableLoading = ref(props.isLoading)
const searchFn = () => {
  let queryParamsObj = {
    dynamicParams: [],
    orderbyParams: [],
    size: 10,
  }
  // 以下为组装添加 动态查询条件
  Array.isArray(cloneColumnList.value) &&
    cloneColumnList.value.forEach((item) => {
      if (item.showHighSearch === true) {
        if (item.editType === 'input') {
          const dynamicItem = {
            name: item.prop,
            queryName: item?.queryName || '',
            ops: 'like',
            val: [item.modelValue?.inputValue || ''],
          }
          // 空
          if (item.modelValue?.isBlank) {
            dynamicItem.ops = 'isBlank'
            queryParamsObj.dynamicParams.push(dynamicItem)
          }
          // 非空
          if (item.modelValue?.notBlank) {
            dynamicItem.ops = 'notBlank'
            queryParamsObj.dynamicParams.push(dynamicItem)
          }

          if (!item.modelValue?.notBlank && !item.modelValue?.isBlank && item.modelValue?.inputValue) {
            queryParamsObj.dynamicParams.push(dynamicItem)
          }
        }
      }
    })
  isTableLoading.value = true
  // 查询接口传参,
  props.queryApi &&
    apiRequestPost(props.queryApi, queryParamsObj)
      .then((res) => {
        isTableLoading.value = false
        if (res.data.success) {
          cloneTableData.value = res.data.data.result
          // props.data.value = res.data.data.result
        } else {
          ElMessage.error(res.data.message)
        }
      })
      .catch((error) => {
        isTableLoading.value = false
        // 处理错误
      })
  // }
}
// 获取列是否必填状态
const getRequiredStatus = (item) => {
  if (item?.required) return true
  if (item?.editable && item?.editConfig?.rules && item?.editConfig?.rules[item.prop]) {
    const tempRules = item?.editConfig?.rules[item.prop]
    let tempStatus = false
    Array.isArray(tempRules) &&
      tempRules.forEach((e) => {
        if (e?.required) {
          tempStatus = true
        }
      })
    return tempStatus
  }
  return false
}
// 用于多选表格，清空用户的选择
const clearSelection = () => {
  tableEl.value.clearSelection()
}
// 返回当前选中的行
const getSelectionRows = () => {
  tableEl.value.getSelectionRows()
}
// 用于多选表格，切换某一行的选中状态， 如果使用了第二个参数，则可直接设置这一行选中与否
const toggleRowSelection = (row: any, selected: boolean) => {
  tableEl.value.toggleRowSelection(row, selected)
}
// 用于多选表格，切换全选和全不选
const toggleAllSelection = () => {
  tableEl.value.toggleAllSelection()
}
// 用于单选表格，设定某一行为选中行， 如果调用时不加参数，则会取消目前高亮行的选中状态。
const setCurrentRow = () => {
  tableEl.value.setCurrentRow()
}
const setCellValue = (rowIndex, prop, val) => {
  if (rowIndex <= cloneTableData.value.length - 1) {
    cloneTableData.value[rowIndex][prop] = val
  }
}
// 操作列表事件 item: 点击按钮对象  rowData 当前行数据 按钮详情：btnInfo
const handleAction = (item, rowData) => {
  const btnInfo = getButtonInfoById(item.id)
  emit('action-click', item, rowData, btnInfo)
}
// 当前行的 key，只写属性
const currentRowKey = ref('')

// 保存提交时校验函数
// const saveValidate = () => {
//   let isPass = true
//   for (let i = 0; i < selectList.value.length; i++) {
//     if (!isPass) return
//     let rowItem = selectList.value[i]
//     for (let j = 0; j < cloneColumnList.value.length; j++) {
//       let columnItem = cloneColumnList.value[j]
//       if (columnItem.required) {
//         if (!rowItem[columnItem.prop]) {
//           isPass = false
//           return Promise.reject(new Error(`${columnItem.label}不能为空`))
//         } else {
//           // 如果非空，并且配置了校验规则，则验证自定义校验规则
//           if (columnItem?.editConfig?.rules) {
//             let rules = columnItem?.editConfig?.rules
//             for (let i = 0; i < rules.length; i++) {
//               let ruleItem = rules[i]
//               if (ruleItem.required) {
//                 if (ruleItem.validator) {
//                   let validatorResult = ruleItem.validator(rowItem[columnItem.prop])
//                   if (validatorResult) {
//         }
//       }
//     }
//   }
//   return Promise.resolve()
// }
const saveValidate = () => {
  // 假设selectList.value和cloneColumnList.value是外部定义的响应式数据
  let errors = [] // 用于收集所有错误

  for (let i = 0; i < selectList.value.length; i++) {
    let rowItem = selectList.value[i]
    for (let j = 0; j < cloneColumnList.value.length; j++) {
      let columnItem = cloneColumnList.value[j]
      if (columnItem.required) {
        if (!rowItem[columnItem.prop]) {
          errors.push(`${columnItem.label}不能为空`)
        } else if (columnItem?.editConfig?.rules) {
          // 如果非空，并且配置了校验规则，则验证自定义校验规则
          let rules = columnItem.editConfig.rules
          for (let k = 0; k < rules.length; k++) {
            // 注意：这里使用了新的循环变量k
            let ruleItem = rules[k]
            if (ruleItem.validator) {
              // 假设validator函数返回一个Promise，该Promise在验证失败时resolve为false，验证成功时resolve为true
              ruleItem
                .validator(rowItem[columnItem.prop])
                .then((validatorResult) => {
                  if (!validatorResult) {
                    // 假设validator在失败时返回false
                    errors.push(`${columnItem.label}不满足自定义校验规则`)
                  }
                })
                .catch((error) => {
                  // 如果validator抛出了错误，也将其添加到错误列表中
                  errors.push(`校验${columnItem.label}时出错: ${error.message}`)
                })
            }
          }
        }
      }
    }
  }
  emit('save-validate-errors', errors)
  // 如果没有错误，返回Promise.resolve()
  if (errors.length === 0) {
    return Promise.resolve()
  } else {
    // 如果有错误，返回Promise.reject()，并带上所有错误信息
    return Promise.reject(new Error(errors.join('，\n')))
  }
}
const getRowValidate = (rowData) => {
  // 获取当前行的校验函数
  const rowValidate = getRowValidate(rowData)
  // 执行校验函数
  return rowValidate()
}
// 行拖拽
const rowDrop = function () {
  // 要拖拽元素的父容器 tbody
  const tbody = document.querySelector('.el-table__body-wrapper tbody')
  Sortable.create(tbody, {
    //  可被拖拽的子元素
    draggable: '.el-table__row',
    onEnd({ newIndex, oldIndex }) {
      // newIndex 拖动到的新的索引
      // oldIndex 没拖动前的索引
      console.log('row-drag', newIndex, oldIndex)
      const currRow = cloneTableData.value.splice(oldIndex, 1)[0]
      cloneTableData.value.splice(newIndex, 0, currRow)
      // emit('row-drag', currRow, oldIndex, newIndex)
    },
  })
}

onMounted(() => {
  // 因为使用了模版就不需要重置 table列设置了
  initTableColumnSetting()
  // 接口获取table设置模版
  getTableConfig()
  if (isUseQueryApi.value) {
    searchFn()
  }
  setTimeout(() => {
    rowDrop()
  }, 3000)
})
defineExpose({
  exportTableToExcel,
  onAddRow,
  addRowCancel,
  clearSelection,
  getSelectionRows,
  toggleRowSelection,
  toggleAllSelection,
  setCurrentRow,
  lockToggle,
  setCellValue,
  selectList,
  onCellChange,
  cloneTableData,
  lastEditCellRowIndex,
  onAddEmptyRow,
  saveValidate,
  cloneColumnList,
  singleElection,
})
</script>
<style lang="less" scoped>
@oy-color-black: #242424;
.oy-table {
  width: 100%;
  padding: 10px 0;
  background: #fff;
  display: flex;
  flex-direction: column;
  border-radius: 6px;
  &:hover {
    box-shadow: 1px 4px 12px 0px rgba(0, 0, 0, 0.16);
    opacity: 0.8;
  }
  .oy-table__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 30px;
    border-bottom: 1px solid #e8e8e8;

    .oy-table__header-name {
      font-size: 16px;
      color: #303133;
      line-height: 28px;
      font-weight: bold;
      i {
        margin-right: 5px;
        color: var(--el-color-primary);
      }
    }

    .oy-table__header-set {
      display: flex;
      align-items: center;

      .set_box {
        display: flex;
        align-items: center;
        margin-left: 16px;

        i {
          font-size: 15px;
          margin-left: 16px;
          color: #989898;

          &:hover {
            cursor: pointer;
            color: var(--el-color-primary);
          }
        }

        &::before {
          content: '';
          display: inline-block;
          height: 14px;
          width: 1px;
          background: #e8e8e8;
        }
      }
    }
  }

  .table-line__height-0 ::v-deep(.cell) {
    line-height: 23px;
  }

  .table-line__height-1 ::v-deep(.cell) {
    line-height: 28px;
  }

  .table-line__height-2 ::v-deep(.cell) {
    line-height: 18px;
  }

  .oy-table__page {
    padding: 20px 30px;
    align-self: flex-end;
  }
}

.set_box__setting {
  max-height: 248px;
  overflow: auto;
  margin-right: -10px;
  padding-right: 10px;

  .setting_header {
    display: flex;
    align-items: center;

    // justify-content: space-between;
    .setting_header__show {
      margin-right: 10px;

      ::v-deep(.el-checkbox__label) {
        font-weight: bold;
        color: @oy-color-black;
      }
    }

    .setting_header__index {
      ::v-deep(.el-checkbox__label) {
        font-weight: bold;
        color: @oy-color-black;
      }
    }

    .setting_header__btn {
      margin-left: 12px;
      padding: 0 8px;
      cursor: pointer;
      font-weight: bold;
      color: var(--el-color-primary);

      &:hover {
        background: var(--el-color-primary-light-8);
        border-radius: 4px;
        opacity: 0.85;
      }

      &:last-child {
        margin-left: 0px;
      }
    }
  }
}

.drag-item {
  display: flex;
  align-items: center;
  width: 100%;

  .drag-item__icon {
    margin: 0 10px;
    font-size: 17px;
    color: #d8d8d8;

    &:hover {
      cursor: move;
    }
  }

  .drag-item__label {
    padding: 0 5px;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: rgba(0, 0, 0, 0.85);
    border-radius: 4px;

    // i {
    //   color: rgba(0,0,0,0.5);
    // }
    &:hover {
      background: var(--el-color-primary-light-8);
      color: var(--el-color-primary);
    }
  }

  .drag-item__flexd {
    i {
      font: 18px;
      margin-right: 5px;

      &:hover {
        cursor: pointer;
      }
    }
  }
}

::v-deep(.el-table thead tr th .cell) {
  color: var(--el-text-color-black);
  font-weight: bold !important;
}
::v-deep(.el-table td.el-table__cell div) {
  margin-bottom: 0px;
}

// .common-text-ellipsis {
//   overflow: hidden;
//   /* 隐藏超出容器的内容 */
//   text-overflow: ellipsis;
//   /* 用省略号表示被截断的文本 */
//   white-space: nowrap;
//   /* 防止文本换行 */
// }
.icon-filter {
  &:hover {
    cursor: pointer;
    color: var(--el-color-primary);
  }
}
.icon-filter__selected {
  color: var(--el-color-primary);
}
.current-row {
  background: var(--el-color-primary-light-9) !important;
}
.edit-form-item {
  ::v-deep(.el-form-item__content .el-form-item__error) {
    margin-top: -16px;
    margin-left: 2px;
  }
}
.edit-hover__class {
  border: 1px transparent dotted;
  padding: 0px 4px;
  height: 30px;
}
.edit-hover__class:hover {
  border-color: var(--el-color-primary);
}
.cell-change__class {
  height: 32px;
}
.cell-change__class:before {
  content: '';
  display: block;
  position: absolute;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 4px;
  border-color: var(--el-color-primary) transparent transparent var(--el-color-primary);
  // margin: -0.45em 0 0 -0.6em;
  margin-left: -4px;
  padding: 0;
  overflow: hidden;
  vertical-align: top;
}
.required-star-class {
  position: relative;
  &:before {
    content: '*'; /* 在元素之前插入内容：星号 */
    color: red; /* 设置星号颜色为红色 */
    font-weight: bold; /* 加粗星号 */
    position: absolute; /* 绝对定位使得星号相对于其最近的定位祖先 */
    left: -12px; /* 调整星号相对于<div>的位置，根据需要调整 */
    top: 1px; /* 根据需要调整垂直位置 */
  }
}
.sort-icon-container {
  position: relative;
  display: inline-block;
  width: 10px;
  height: 6px;
  margin: 0 8px;
  &:hover {
    cursor: pointer;
  }
}

.sort-icon {
  position: absolute;
  width: 0;
  height: 0;
  border-style: solid;
  transform-origin: center;
}

/* 下方三角形 */
.sort-icon.down {
  border-width: 0 5px 6px 5px;
  border-color: transparent transparent #bfbfbf transparent;
  top: 1px;
  left: 0;
  transform: rotate(180deg); /* 旋转180度使得三角形朝上 */
}
.sort-icon.down.down-active {
  border-color: transparent transparent var(--el-color-primary) transparent;
}
/* 上方三角形 */
.sort-icon.up {
  border-width: 6px 5px 0 5px;
  border-color: #bfbfbf transparent transparent transparent;
  top: -6px; /* 调整位置使其位于下方三角形之上 */
  transform: rotate(180deg); /* 旋转180度使得三角形朝上 */
  left: 0;
}
.sort-icon.up.up-active {
  border-color: var(--el-color-primary) transparent transparent transparent;
}
.insert-btn__class {
  width: 100%;
  margin: 10px 0;
}
.action-dropdown-link {
  font-size: 24px;
  color: var(--el-color-primary);
}
.cell-text__align-center {
  width: 100%;
  text-align: center;
}
.cell-text__align-right {
  width: 100%;
  text-align: right;
}
.cell-text__align-left {
  width: 100%;
  text-align: left;
}
.required-tooltip {
  ::v-deep(.el-popper.is-customized) {
    /* Set padding to ensure the height is 32px */
    padding: 6px 12px;
    background: linear-gradient(180deg, red 0%, #ce9748 100%);
    box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.1);
  }

  &:v-deep(.el-popper.is-customized .el-popper__arrow::before) {
    background: linear-gradient(45deg, red, #ce9748) !important;
    right: 0;
  }
}
// .cell-action {
//   background: red;
//   &:hover {
//     transform: scale(1.3);
//   }
// }
.required-valiate-error {
  box-shadow: 0 0 0 1px var(--el-input-focus-border-color) inset;
}
.drag-row__icon {
  margin: 0 10px;
  font-size: 22px;
  color: #d8d8d8;
  &:hover {
    cursor: move;
  }
}
</style>
